#pragma once
#include "udp_socket.hpp"
// C 式写法
// // typedef void (*Handler)(const std::string& req, std::string* resp);
// // C++ 11 式写法, 能够兼容函数指针, 仿函数, 和 lamda
 #include <functional>
 typedef std::function<void (const std::string&, std::string* resp)> Handler;
class UdpServer {
public:
UdpServer() {
assert(sock_.Socket());
}
~UdpServer() {
sock_.Close();
}
bool Start(const std::string& ip, uint16_t port, Handler handler) {
// 1. 创建 socket
 // 2. 绑定端口号
 bool ret = sock_.Bind(ip, port);
 if (!ret) {
 return false;
 }
 // 3. 进入事件循环
 for (;;) {
 // 4. 尝试读取请求
 std::string req;
 std::string remote_ip;
 uint16_t remote_port = 0;
 bool ret = sock_.RecvFrom(&req, &remote_ip, &remote_port);
 if (!ret) {
continue;
}
std::string resp;
// 5. 根据请求计算响应
 handler(req, &resp);
 // 6. 返回响应给客户端
 sock_.SendTo(resp, remote_ip, remote_port);
 printf("[%s:%d] req: %s, resp: %s\n", remote_ip.c_str(), remote_port,
 req.c_str(), resp.c_str());
 }
 sock_.Close();
 return true;
 }
 private:
 UdpSocket sock_;
 };
